﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Web;
using System.Data;

namespace Yu.Cms.Common
{
    public class FSO
    {
        /// <summary>
        /// 复制目录
        /// </summary>
        /// <param name="oldDir">旧目录</param>
        /// <param name="newDir">新目录</param>
        public static void CopyDirectory(string oldDir, string newDir)
        {
            try
            {
                DirectoryInfo dInfo = new DirectoryInfo(oldDir);
                CopyDirInfo(dInfo, oldDir, newDir);
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
        }

        /// <summary>
        /// 复制目录
        /// </summary>
        /// <param name="od"></param>
        /// <param name="oldDir"></param>
        /// <param name="newDir"></param>
        private static void CopyDirInfo(DirectoryInfo od, string oldDir, string newDir)
        {
            if (!IsExist(newDir, FsoMethod.Folder))
            {
                Create(newDir, FsoMethod.Folder);
            }
            DirectoryInfo[] dirs = od.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                CopyDirInfo(dir, dir.FullName, newDir + dir.FullName.Replace(oldDir, ""));
            }
            FileInfo[] files = od.GetFiles();
            foreach (FileInfo file in files)
            {
                CopyFile(file.FullName, newDir + file.FullName.Replace(oldDir, ""));
            }
        }

        /// <summary>
        /// 创建DataTable
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="child"></param>
        /// <returns></returns>
        public static DataTable copyDT(DataTable parent, DataTable child)
        {
            for (int i = 0; i < child.Rows.Count; i++)
            {
                DataRow dr = parent.NewRow();
                for (int j = 0; j < parent.Columns.Count; j++)
                {
                    dr[j] = child.Rows[i][j];
                }
                parent.Rows.Add(dr);
            }
            return parent;
        }


        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="oldFile"></param>
        /// <param name="newFile"></param>
        public static void CopyFile(string oldFile, string newFile)
        {
            try
            {
                File.Copy(oldFile, newFile, true);
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
        }

        /// <summary>
        /// 以文件流形式复制
        /// </summary>
        /// <param name="oldPath"></param>
        /// <param name="newPath"></param>
        /// <returns></returns>
        public static bool CopyFileStream(string oldPath, string newPath)
        {
            try
            {
                FileStream fsOld = new FileStream(oldPath, FileMode.Open, FileAccess.Read);
                FileStream fsNew = new FileStream(newPath, FileMode.Create, FileAccess.Write);
                BinaryReader br = new BinaryReader(fsOld);
                BinaryWriter bw = new BinaryWriter(fsNew);
                br.BaseStream.Seek((long)0, SeekOrigin.Begin);
                br.BaseStream.Seek((long)0, SeekOrigin.End);
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    bw.Write(br.ReadByte());
                }
                br.Close();
                bw.Close();
                fsOld.Flush();
                fsOld.Close();
                fsNew.Flush();
                fsNew.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 创建文件系统
        /// </summary>
        /// <param name="file"></param>
        /// <param name="method"></param>
        public static void Create(string file, FsoMethod method)
        {
            try
            {
                if (method == FsoMethod.File)
                {
                    WriteFile(file, "");
                }
                else if (method == FsoMethod.Folder)
                {
                    Directory.CreateDirectory(file);
                }
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="FilePath">删除的文件路径</param>
        /// <param name="PathType">删除文件路径类型</param>
        /// <returns>成功/失败</returns>
        public static bool DeleteFile(string FilePath, DeleteFilePathType PathType)
        {
            bool rBool = false;
            switch (PathType)
            {
                case DeleteFilePathType.DummyPath:
                    FilePath = HttpContext.Current.Server.MapPath(FilePath);
                    break;
                case DeleteFilePathType.NowDirectoryPath:
                    FilePath = HttpContext.Current.Server.MapPath(FilePath);
                    break;
                case DeleteFilePathType.PhysicsPath:
                    break;
            }
            if (File.Exists(FilePath))
            {
                File.Delete(FilePath);
                rBool = true;
            }
            return rBool;
        }


        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="method"></param>
        public static void Delete(string file, FsoMethod method)
        {
            try
            {
                if (method == FsoMethod.File)
                {
                    File.Delete(file);
                }
                if (method == FsoMethod.Folder)
                {
                    Directory.Delete(file, true);
                }
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
        }

        private static long[] DirInfo(DirectoryInfo d)
        {
            long[] intResult = new long[3];
            long Size = 0;
            long Dirs = 0;
            long Files = 0;
            FileInfo[] files = d.GetFiles();
            Files += files.Length;
            foreach (FileInfo file in files)
            {
                Size += file.Length;
            }
            DirectoryInfo[] dirs = d.GetDirectories();
            Dirs += dirs.Length;
            foreach (DirectoryInfo dir in dirs)
            {
                Size += DirInfo(dir)[0];
                Dirs += DirInfo(dir)[1];
                Files += DirInfo(dir)[2];
            }
            intResult[0] = Size;
            intResult[1] = Dirs;
            intResult[2] = Files;
            return intResult;
        }

        private static DataTable getDirectoryAllInfo(DirectoryInfo d, FsoMethod method)
        {
            DataRow Dr;
            DataTable Dt = new DataTable();
            Dt.Columns.Add("name");
            Dt.Columns.Add("rname");
            Dt.Columns.Add("content_type");
            Dt.Columns.Add("type");
            Dt.Columns.Add("path");
            Dt.Columns.Add("creatime");
            Dt.Columns.Add("size");
            DirectoryInfo[] dirs = d.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                if (method == FsoMethod.File)
                {
                    Dt = copyDT(Dt, getDirectoryAllInfo(dir, method));
                }
                else
                {
                    Dr = Dt.NewRow();
                    Dr[0] = dir.Name;
                    Dr[1] = dir.FullName;
                    Dr[2] = "";
                    Dr[3] = 1;
                    Dr[4] = dir.FullName.Replace(dir.Name, "");
                    Dr[5] = dir.CreationTime;
                    Dr[6] = "";
                    Dt.Rows.Add(Dr);
                    Dt = copyDT(Dt, getDirectoryAllInfo(dir, method));
                }
            }
            if (method != FsoMethod.Folder)
            {
                FileInfo[] files = d.GetFiles();
                foreach (FileInfo file in files)
                {
                    Dr = Dt.NewRow();
                    Dr[0] = file.Name;
                    Dr[1] = file.FullName;
                    Dr[2] = file.Extension.Replace(".", "");
                    Dr[3] = 2;
                    Dr[4] = file.DirectoryName + @"\";
                    Dr[5] = file.CreationTime;
                    Dr[6] = file.Length;
                    Dt.Rows.Add(Dr);
                }
            }
            return Dt;
        }

        /// <summary>
        /// 创建DataTable对象
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static DataTable getDirectoryAllInfos(string dir, FsoMethod method)
        {
            DataTable Dt;
            try
            {
                DirectoryInfo dInfo = new DirectoryInfo(dir);
                Dt = getDirectoryAllInfo(dInfo, method);
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
            return Dt;
        }

        public static DataTable getDirectoryInfos(string dir, FsoMethod method)
        {
            DataRow Dr;
            int i;
            DataTable Dt = new DataTable();
            Dt.Columns.Add("name");
            Dt.Columns.Add("type");
            Dt.Columns.Add("size");
            Dt.Columns.Add("content_type");
            Dt.Columns.Add("createTime");
            Dt.Columns.Add("lastWriteTime");
            if (method != FsoMethod.File)
            {
                for (i = 0; i < getDirs(dir).Length; i++)
                {
                    Dr = Dt.NewRow();
                    DirectoryInfo d = new DirectoryInfo(getDirs(dir)[i]);
                    Dr[0] = d.Name;
                    Dr[1] = 1;
                    Dr[2] = "";
                    Dr[3] = "";
                    Dr[4] = d.CreationTime;
                    Dr[5] = d.LastWriteTime;
                    Dt.Rows.Add(Dr);
                }
            }
            if (method != FsoMethod.Folder)
            {
                for (i = 0; i < getFiles(dir).Length; i++)
                {
                    Dr = Dt.NewRow();
                    FileInfo f = new FileInfo(getFiles(dir)[i]);
                    Dr[0] = f.Name;
                    Dr[1] = 2;
                    Dr[2] = f.Length;
                    Dr[3] = f.Extension.Replace(".", "");
                    Dr[4] = f.CreationTime;
                    Dr[5] = f.LastWriteTime;
                    Dt.Rows.Add(Dr);
                }
            }
            return Dt;
        }

        public static long[] getDirInfos(string dir)
        {
            long[] intResult = new long[3];
            DirectoryInfo d = new DirectoryInfo(dir);
            return DirInfo(d);
        }

        private static string[] getDirs(string dir)
        {
            return Directory.GetDirectories(dir);
        }

        private static string[] getFiles(string dir)
        {
            return Directory.GetFiles(dir);
        }

        public static bool IsExist(string file, FsoMethod method)
        {
            try
            {
                if (method == FsoMethod.File)
                {
                    return File.Exists(file);
                }
                if (method == FsoMethod.Folder)
                {
                    return Directory.Exists(file);
                }
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
            return false;
        }

        private static bool IsImageFile(HttpPostedFile postedFile)
        {
            string fileExtension = Path.GetExtension(postedFile.FileName);
            string fileExtensions = ".gif|.jpg|";
            if (fileExtensions.IndexOf(fileExtension) == -1)
            {
                return false;
            }
            return true;
        }

        public static void Move(string oldFile, string newFile, FsoMethod method)
        {
            try
            {
                if (method == FsoMethod.File)
                {
                    File.Move(oldFile, newFile);
                }
                if (method == FsoMethod.Folder)
                {
                    Directory.Move(oldFile, newFile);
                }
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
        }

        public static string ReadFile(string file)
        {
            string strResult = "";
            FileStream fStream = new FileStream(file, FileMode.Open, FileAccess.Read);
            StreamReader sReader = new StreamReader(fStream, Encoding.Default);
            try
            {
                try
                {
                    strResult = sReader.ReadToEnd();
                }
                catch
                {
                }
            }
            finally
            {
                fStream.Flush();
                fStream.Close();
                sReader.Close();
            }
            return strResult;
        }

        public static bool SaveImageFile(HttpPostedFile postedFile, string folder, out string clientImgPath, out string serverImgUrl)
        {
            clientImgPath = "";
            serverImgUrl = "";
            if (postedFile == null)
            {
                return false;
            }
            if (!IsImageFile(postedFile))
            {
                return false;
            }
            string imageFolder = folder;
            DateTime now = DateTime.Now;
            string TempFolder = string.Concat(new object[] { "/", now.Year, "", now.Month, "/" });
            string folderName = HttpContext.Current.Server.MapPath(imageFolder) + TempFolder;
            if (!Directory.Exists(folderName))
            {
                Directory.CreateDirectory(folderName);
            }
            string newFileName = string.Format("{0}{1}{2}{3}{4}{5}", new object[] { now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, Path.GetExtension(postedFile.FileName) });
            postedFile.SaveAs(folderName + newFileName);
            clientImgPath = postedFile.FileName;
            serverImgUrl = System.Configuration.ConfigurationManager.AppSettings["MessageImagePath"] + TempFolder + newFileName;

            return true;
        }

        public static string WriteFile(string file, string fileContent)
        {
            string CS;
            FileInfo f = new FileInfo(file);
            if (!Directory.Exists(f.DirectoryName))
            {
                Directory.CreateDirectory(f.DirectoryName);
            }
            FileStream fStream = new FileStream(file, FileMode.Create, FileAccess.Write);
            StreamWriter sWriter = new StreamWriter(fStream, Encoding.GetEncoding("gb2312"));
            try
            {
                sWriter.Write(fileContent);
                CS = fileContent;
            }
            catch (Exception exc)
            {
                throw new Exception(exc.ToString());
            }
            finally
            {
                sWriter.Flush();
                fStream.Flush();
                sWriter.Close();
                fStream.Close();
            }
            return CS;
        }

        public static void WriteFile(string file, string fileContent, bool Append)
        {
            FileInfo f = new FileInfo(file);
            if (!Directory.Exists(f.DirectoryName))
            {
                Directory.CreateDirectory(f.DirectoryName);
            }
            StreamWriter sWriter = new StreamWriter(file, Append, Encoding.GetEncoding("UTF-8"));
            try
            {
                try
                {
                    sWriter.Write(fileContent);
                }
                catch (Exception exc)
                {
                    throw new Exception(exc.ToString());
                }
            }
            finally
            {
                sWriter.Flush();
                sWriter.Close();
            }
        }

        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="fileContent"></param>
        /// <param name="Append"></param>
        /// <param name="Encode"></param>
        public static void WriteFile(string file, string fileContent, bool Append, string Encode)
        {
            FileInfo f = new FileInfo(file);
            if (!Directory.Exists(f.DirectoryName))
            {
                Directory.CreateDirectory(f.DirectoryName);
            }
            StreamWriter sWriter = new StreamWriter(file, Append, Encoding.GetEncoding(Encode));
            try
            {
                try
                {
                    sWriter.Write(fileContent);
                }
                catch (Exception exc)
                {
                    throw new Exception(exc.ToString());
                }
            }
            finally
            {
                sWriter.Flush();
                sWriter.Close();
            }
        }
    }
}
